package sk.vrto.service.dao.inmemory;

import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Multimap;
import sk.vrto.domain.Email;
import sk.vrto.domain.User;
import sk.vrto.service.dao.ContactRepository;
import sk.vrto.service.dao.DataAccessException;
import sk.vrto.service.dao.EmailRepository;

import java.util.Arrays;
import java.util.Collection;

/**
 * EmailRepository that stores all the emails directly in memory.
 * Repository existence is bound to the application lifecycle.
 */
public class InMemoryEmailRepository implements EmailRepository {

    private Multimap<User, Email> emails = ArrayListMultimap.create();
    private ContactRepository contactRepository;

    private static final String CONTENT = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer facilisis imperdiet nibh in dictum. In purus dui, euismod vel gravida sit amet, adipiscing sit amet erat. Nullam nec erat dui, in luctus lorem. Suspendisse tellus elit, tristique mattis lacinia ac, viverra nec tortor. Cras sagittis enim at urna auctor sodales vel at lectus. Aenean erat felis, consequat sed mollis eu, lobortis id nisi. Aenean arcu nulla, condimentum nec vulputate a, pharetra in sapien. Vestibulum id leo neque. Sed nec nunc nisi, in dignissim velit. Vestibulum fringilla augue ac nisi cursus aliquam. Nulla vitae ante imperdiet magna ornare placerat nec at metus.";

    /**
     * Requires contact repository because it creates dummy emails.
     * Therfore it has to obtain contacts, since every mail has corresponding contact.
     * @param contactRepository ContactRepository to use
     */
    public InMemoryEmailRepository(ContactRepository contactRepository) {
        this.contactRepository = contactRepository;
    }

    public void initForUser(User user) {
        emails.putAll(user, Arrays.asList(
                createEmail(1, new Email(contactRepository.find("gmail@chucknorris.com"), "So you building bridge?", CONTENT)),
                createEmail(2, new Email(contactRepository.find("gretzky@nhl.com"), "About the lockout ...", CONTENT)),
                createEmail(3, new Email(contactRepository.find("lemieux@nhl.com"), "Yeah its fine if Jagr plays for Kladno now", CONTENT)),
                createEmail(4, new Email(contactRepository.find("schwarzie@expedanbles.com"), "I really did break that Smart door :D", CONTENT)),
                createEmail(5, new Email(contactRepository.find("gosling@java.com"), "Liquid Robotics info", CONTENT)),
                createEmail(6, new Email(contactRepository.find("walter.white@breakingbad.com"), "Episode S05E8", CONTENT)),
                createEmail(7, new Email(contactRepository.find("bigbadboss@enclave.com"), "Time to die mutie", CONTENT)),
                createEmail(8, new Email(contactRepository.find("ovi8@caps.com"), "Slysis mne?", CONTENT))
        ));
    }

    @Override
    public Email find(Integer key) {
        for (Email email : emails.values()) {
            if (key.equals(email.getId())) {
                return email;
            }
        }
        return null;
    }

    @Override
    public Collection<Email> load() {
        return emails.values();
    }

    @Override
    public void insert(Email email) {
        emails.put(email.getUser(), email);
    }

    @Override
    public void update(Email email) {
        throw new DataAccessException("Cannot update email within in-memory implementation service!");
    }

    @Override
    public void delete(Email email) {
        emails.remove(email.getUser(), email);
    }

    @Override
    public Collection<Email> loadEmailsForUser(User user) {
        return emails.get(user);
    }

    private Email createEmail(int id, Email email) {
        email.setId(id);
        return email;
    }

    public ContactRepository getContactRepository() {
        return contactRepository;
    }
}
